package com.nyt.org.modules.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.nyt.org.common.utils.CacheUtil;
import com.nyt.org.common.utils.DateUtil;
import com.nyt.org.common.utils.HttpUtil;
import com.nyt.org.common.utils.SignKit;
import com.nyt.org.modules.api.constant.Methods;
import com.nyt.org.modules.api.constant.Status;
import com.nyt.org.modules.api.model.BaseResponse;
import com.nyt.org.modules.api.model.PublicRequest;
import com.nyt.org.modules.api.model.PublicResponse;
import com.nyt.org.modules.api.model.SysApiUserModel;
import com.nyt.org.modules.api.service.SysUserService;
import com.nyt.org.modules.api.utils.MethodsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.List;

@RestController
public class apiController {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SysUserService sysUserService;

    /**
     * 接口鉴权
     */
    @RequestMapping("/api")
    public void signCheck(HttpServletRequest request, HttpServletResponse response){
        //获取请求的IP
        String IPAddr = HttpUtil.getClientIp(request);
        // 读取请求参数
        String jsonStr = getRequestStr(request);
        // 转换成对象处理
        JSONObject reqData = JSON.parseObject(jsonStr);
        PublicRequest publicReq = reqData.getObject("publicrequest", PublicRequest.class);
        // body可能为非数组，统一转换数组处理
        String bodytemp;
        Object body = reqData.get("body");
        if (body instanceof List) {// 判断上传的是否数组
            // 获得bodytemp
            bodytemp = JSON.toJSONString(body, SerializerFeature.MapSortField, SerializerFeature.DisableCircularReferenceDetect);
            // 然后封装成统一格式
            JSONObject jsonObj = new JSONObject();
            //jsonObj.put("data", body);
            jsonObj.put("total", ((List) body).size());
            body = jsonObj;
        } else {
            // 获得bodytemp
            bodytemp = JSON.toJSONString(body, SerializerFeature.MapSortField, SerializerFeature.DisableCircularReferenceDetect);
        }
        //开始验签逻辑
        try{
            //requestid是否重复提交
//            System.out.println("requestid:"+publicReq.getRequestid());
//            Object falg = CacheUtil.get("apiReqCache",publicReq.getRequestid());
//            if( falg != null ){
//                doResponse(response, publicReq, "10003");
//                return;
//            }else {
//                CacheUtil.put("apiReqCache", publicReq.getRequestid(), IPAddr);
//            }
            //requesttime是否再15分钟内
//            if( ! DateUtil.isDiffInMins(publicReq.getRequesttime(),15) ){
//                doResponse(response,publicReq,"10001");
//                return;
//            }
            //查找secrekey
            SysApiUserModel sysApiUser = sysUserService.selectOne(publicReq.getAccesskey());
            if( sysApiUser == null ){
                doResponse(response, publicReq, "10002");
                return;
            }
            //判断接口是否再集合中
            if( !Methods.exist(publicReq.getMethod())){
                doResponse(response, publicReq, "10005");
                return;
            }

            //开始验签
            if( "MD5".equals(publicReq.getSignmethod()) ){
//                Boolean isSign = SignKit.checkSignature(publicReq.getSigndata(),publicReq.getAccesskey(),
//                        sysApiUser.getSecretkey(),bodytemp,publicReq.getRequestid(),publicReq.getRequesttime());
                Boolean isSign = true;
                if(isSign){
                    System.out.println("body值为："+body.toString());
                    //处理
                    MethodsUtil.handlerMethods(publicReq.getMethod(),response,publicReq,(JSONObject) body);
                    return;
                }
                doResponse(response, publicReq, "10004");
                return;
            }



        }catch(Exception e) {
            log.error("验签程序异常，json: \n" + jsonStr);
            doResponse(response, publicReq, "99999");
            e.printStackTrace();
        }


    }



    /**
     * 获取request中的请求参数
     *
     * @param request
     * @return
     */
    private String getRequestStr(HttpServletRequest request) {
        StringBuffer jsonParam = new StringBuffer();
        BufferedReader reader = null;
        try {
            if (request.getContentLength() > 0) {
                reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
                String line;
                while ((line = reader.readLine()) != null)
                    jsonParam.append(line);
                reader.close();
            }
        } catch (IOException e) {
            log.error("参数转换成json异常", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error("json转换成功，但是inputstream.close异常: ", e);
                }
            }
        }
        return jsonParam.toString();
    }

    /**
     * 返回响应
     *
     * */
    private void doResponse(ServletResponse response, PublicRequest publicReq, String statuscode) {
        Writer writer = null;
        try {
            if (!"00000".equals(statuscode)) {  // 日志
                log.info("验签失败, 错误代码：" + statuscode + ", 错误信息：" + Status.getMsg(statuscode)
                        + ", accesskey：" + publicReq.getAccesskey());
            }

            // 准备返回信息
            BaseResponse respData = new BaseResponse(
                    new PublicResponse(publicReq.getMethod(), publicReq.getAccesskey(), publicReq.getRequestid(),
                            DateUtil.nowFormat("yyyyMMddHHmmss"), statuscode, Status.getMsg(statuscode), ""),
                    null);
            response.setCharacterEncoding("UTF-8");
            writer = response.getWriter();
            writer.write(JSON.toJSONString(respData));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
